package com.kamistoat.meimeistore.product.service.impl;

import com.kamistoat.meimeistore.product.service.AttrService;
import com.kamistoat.meimeistore.product.vo.AttrGroupWithAttrVo;
import com.kamistoat.meimeistore.product.vo.thymeleaf.skuItem.SpuItemBaseAttrGroupVo;
import com.kamistoat.meimeistore.product.dao.AttrGroupDao;
import com.kamistoat.meimeistore.product.entity.AttrGroupEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kamistoat.common.utils.PageUtils;
import com.kamistoat.common.utils.Query;

import com.kamistoat.meimeistore.product.service.AttrGroupService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 如果传入的categoryId非零，则只查询catelogId下对应的分组属性。
     * 如果是零，就查询所有的分组属性。
     *
     * @param params     分页属性
     * @param categoryId 指定查询对象
     * @return PageUtils分页包装类，java库类直接使用
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params, long categoryId) {
        // 首先要获取包含在分页属性中的查询关键字，两种查询情况下，都要根据key进行模糊查询
        String key = (String) params.get("key");
        // 规定当没有点击菜单时，查询全部属性，要求此时前端传categoryId = 0
        if (categoryId == 0) {
            // 脚手架为每一个Entity都生成了page方法
            // page方法的第一个参数是固定的，都是new Query<对应的Entity>().getPage(分页参数)
            // page方法的第二个参数也是固定的，是new QueryWrapper<对应订单参数>().设置查询条件方法
            // 因为这里是全部查询，所以不用设置catelog_id的查询条件，只设置模糊查询条件
            // 注意左边的数据类型，是一个IPage类
            IPage<AttrGroupEntity> pageData = this.page(new Query<AttrGroupEntity>().getPage(params),
                    new QueryWrapper<AttrGroupEntity>().eq("attr_group_id", key).or()
                            .like("attr_group_name", key).or()
                            .like("descript", key));
            return new PageUtils(pageData);
        } else {
            // 否则就从pms_attr_group去查询对应categoryId下于关键字模糊匹配的所有属性
            // 使用QueryWrapper构建查询条件，然后向这个查询条件类中存放查询条件，首先必然是catelog_id=categoryId
            // 注意.eq()条件的书写格式，.eq("数据库中表的列名",要求的值)
            QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", categoryId);
            // 如果key不为空，就继续添加条件
            // 其实加不加这个判断完全不影响，因为即便key是空，.eq/.like都能合法进行
            if (!StringUtils.isEmpty(key)) {
                // 因为这里的逻辑是：{菜单id相等} and {属性分组id相等 or 属性分组名称相似 or 属性分组描述相似}
                // 所以在.and()中写一个箭头函数，来包含进所有的or逻辑
                // or逻辑由于都是同级的，所以直接一直用.or()往后叠加就可以
                wrapper.and((obj) -> {
                    obj.eq("attr_group_id", key).or().like("attr_group_name", key).or().like("descript", key);
                });
            }
            // 依然使用this.page方法，只不过这次的查询就是刚刚配置好的查询条件
            IPage<AttrGroupEntity> pageData = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
            return new PageUtils(pageData);
        }
    }

    /**
     * 根据三级菜单的Id，查询属性分组列表，嵌套属性列表
     *
     * @param catelogId 三级分类ID
     * @return 属性分组列表
     */
    @Override
    @Transactional
    public List<AttrGroupWithAttrVo> getAttrGroupWithAttr(Long catelogId) {
//        ①、从pms_attr_group中根据catelog_id查询出AttrGroupEntity，制作成列表。
//        ②、流处理，对每一个AttrGroupEntity，根据其attr_group_id，从attr_attrgroup_relation表中查出attrId构成的List，
//              再根据这个List，去pms_attr中查出AttrEntity，制作成List，嵌套进AttrGroup中。
        List<AttrGroupEntity> attrGroupEntityList =
                baseMapper.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        if (attrGroupEntityList.size() == 0) {
            return Collections.emptyList();
        } else {
            List<AttrGroupWithAttrVo> attrGroupWithAttrVoList = attrGroupEntityList.stream().map((attrGroupEntity) -> {
                AttrGroupWithAttrVo groupWithAttrVo = new AttrGroupWithAttrVo();
                BeanUtils.copyProperties(attrGroupEntity, groupWithAttrVo);
                groupWithAttrVo.setAttrs(attrService.getAttrRelation(groupWithAttrVo.getAttrGroupId()));
                return groupWithAttrVo;
            }).collect(Collectors.toList());
            return attrGroupWithAttrVoList;
        }
    }

    /**
     * Thymeleaf专用。用于查询sku商品详情时，根据其spuId将基础属性分组+基础属性都查出来
     *
     * @param spuId skuId的spuId
     * @param catalogId skuId所属的catalogId
     * @return 列表
     */
    @Override
    public List<SpuItemBaseAttrGroupVo> getAttrGroupWithAttrBySpuId(Long spuId, Long catalogId) {
        List<SpuItemBaseAttrGroupVo> spuItemBaseAttrGroupVoList =
                baseMapper.getAttrGroupWithAttrBySpuId(spuId,catalogId);
        return spuItemBaseAttrGroupVoList;
    }
}